<template>
  <div>
    <el-upload
      :class="{hidden: fileList.length >= limit}"
      action="#"
      list-type="picture-card"
      accept="image/png, image/jpeg"
      :multiple="true"
      :drag="true"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
      :http-request="uploaddImg"
      :on-change="handleChange"
      :file-list="fileList"
      :limit="limit"
      :before-upload="handleBeforeUpload"
    >
      <i class="el-icon-plus" />
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt />
    </el-dialog>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
export default {
  name: 'UploadImg',
  components: {},
  model: {
    prop: 'imgUrl',
    event: 'change'
  },
  props: {
    size: {
      type: Number,
      default: 1
    },
    limit: {
      type: Number,
      default: 1
    },
    imgArr: {
      type: Array,
      default: null
    },
    imgUrl: {
      type: String,
      default: undefined
    }
  },
  data() {
    return {
      cos: null,
      dialogImageUrl: '',
      dialogVisible: false,
      fileList: []
    }
  },
  computed: {
    ...mapGetters([
      'cosInstance'
    ])
  },
  watch: {
    imgUrl: {
      immediate: true,
      handler(nVal) {
        if (nVal === undefined || nVal === this.fileList[0]?.url) return
        if (nVal) {
          this.fileList = [{
            uid: parseInt(Math.random() * 99999999) + Date.now(),
            url: nVal
          }]
        } else {
          this.fileList = []
        }
      }
    }
  },
  created() {
    this.$store.dispatch('user/newCos', this.loginForm)
  },
  mounted() {},
  methods: {
    // 文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用，注意：删除图片时不会触发
    handleChange(file, fileList) {
      this.fileList = fileList
    },
    handleRemove(file, fileList) {
      this.fileList = fileList
      this.emitImg()
    },
    emitImg() {
      if (Array.isArray(this.imgArr)) {
        const img_arr = this.fileList.map(item => item.url)
        this.$emit('update:img-arr', img_arr)
      } else if (this.imgUrl !== undefined) {
        this.$emit('change', this.fileList.length > 0 ? this.fileList[0].url : '')
      }
    },
    handleBeforeUpload(file) {
      if (file.size > 1024 * 1024 * this.size) {
        this.$message.error(`上传的图片不能超过${this.size}M`)
        return false
      }
    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    async  uploaddImg(file) {
      // 从fileList里找到要上传的那张图片
      const uid = file.file.uid
      const upload_file = this.fileList.find(item => item.uid === uid)
      // 把要上传的图片状态该为上传中uploading
      upload_file.status = 'uploading'
      // 再给上传中的图片赋值上传进度条（刚开始为0%）
      upload_file.percentage = 0

      const i = upload_file.name.lastIndexOf('.')
      const ext = upload_file.name.slice(i)

      try {
        const { Location } = await this.cosInstance.putObject({
          Bucket: 'igelato-1257288972', /* 填写自己的bucket，必须字段 */
          Region: 'ap-beijing', /* 存储桶所在地域，必须字段 */
          Key: 'goods_img/' + parseInt(Math.random() * 999999) + Date.now() + ext, /* 存储在桶里的对象键（例如1.jpg，a/b/test.txt），必须字段 */
          Body: upload_file.raw, // 上传文件对象
          SliceSize: 1024 * 1024 * 5, /* 触发分块上传的阈值，超过5MB使用分块上传，小于5MB使用简单上传。可自行设置，非必须 */
          onProgress: function(progressData) {
            upload_file.percentage = progressData.percent * 100
          }
        })

        upload_file.status = 'success'
        // upload_file里的url改变成腾讯云服务器图片的url，this.fileList里的这张图片的url也就改了
        upload_file.url = 'https://' + Location

        this.emitImg()
      } catch (error) {
        this.fileList = this.fileList.filter(item => item.uid !== uid)
        this.$message.error(`上传的图片失败！请重新上传`)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep {
  .el-upload-dragger {
    width: 148px !important;
    height: 148px !important;
  }
  .hidden {
    .el-upload--picture-card {
      display: none !important;
    }
  }

  // 去掉添加或删除图片的动画
  .el-upload-list__item {
    transition: none !important;
  }
}
</style>
